package cn.com.cym.gamezao.util;

import cn.com.cym.gamezao.base.ConditionItem;
import cn.com.cym.gamezao.base.ResultResponse;
import cn.com.cym.gamezao.base.SearchPage;
import cn.com.cym.gamezao.entity.LocalFile;
import cn.com.cym.gamezao.exception.BaseException;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 公用的方法
 */
public class CommonUtils {


    /**
     * 可选字符
     */
    private static final String[] optionalChar="abcdefghijkmnpqrstuvwxwzABCDEFGHIJKLMNPQRSTUVWXYZ".split("");

    private static final String[] optionalNum="23456789".split("");


    /**
     * 判断字符串是否为空
     * @param str 字符串
     * @return flag
     */
    public static boolean isEmpty(String str){
        return "".equals(str) || str==null;
    }

    /**
     * 判断字符串是否不为空
     * @param str 字符串
     * @return flag
     */
    public static boolean isNotEmpty(String str){
        return !isEmpty(str);
    }

    public static boolean isNotEmpty(Object str){
        return str!=null && !isEmpty(str.toString());
    }


    /**
     * 判断当前系统为windows 还是 linux
     * @return flag
     */
    public static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }


    /**
     * 获取文件所在位置
     * @param uuidName uuid
     * @return string
     */
    public static String filePath(String uuidName){
        String path="";
        //判断是否为windows
        if(isWindows()){
            path="D:/fileUpload/";
        }else{
            path="/usr/project/lostfile";
        }
        File file=new File(path);
        if(!file.exists() && !file.isDirectory()){
            file.mkdir();
        }
        return path+uuidName;
    }


    /**
     * 清理并重新生成文件
     * @param fileName
     * @return
     */
    public static String clearIfExistFile(String fileName){
        String path="";
        //判断是否为windows
        if(isWindows()){
            path="D:/fileUpload/";
        }else{
            path="/usr/project/lostfile/";
        }
        File file=new File(path+fileName);
        //file.deleteOnExit(); 在此次不可使用该方法，该方法是作为当前线程结束后再执行删除操作。
        if(file.exists()){
            file.delete();
        }
        return path+fileName;
    }



    /**
     * 文件存储到服务器上
     * @param localFile localFile
     * @param file file
     */
    public static void  saveFile(LocalFile localFile, MultipartFile file){
        File dest=new File(CommonUtils.filePath(localFile.getUuidName()+"."+localFile.getSuffix()));
        try{
            file.transferTo(dest);
        }catch (IOException e) {
           throw new BaseException(e.getMessage(),new ResultResponse("文件存储服务器失败",500)) ;
        }
    }


    /**
     *
     * @param date
     * @return
     */
    public static LocalDate dateToLocalDate(Date date){
        LocalDate localDate = dateToLocalDateTime(date).toLocalDate();
        return  localDate;
    }

    /**
     *
     * @param date
     * @return
     */

    public static LocalDateTime dateToLocalDateTime(Date date){
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return  localDateTime;
    }




    /**
     * 时间转字符串
     * @param date date
     * @param formatter for
     * @return s
     */
    public  static String  dateFormat(Date date, SimpleDateFormat formatter){
        String format = formatter.format(date);
        return format;
    }


    /**
     * 获取前后天数的日期
     * @param num
     * @return
     */
    public static Date nextDate(int num){
        Calendar calendar=new GregorianCalendar();

        calendar.setTime(new Date());

        calendar.add(Calendar.DATE,num);

        return  calendar.getTime();
    }


    /**
     * 分页查询公用查询条件
     * @param fieldMap f
     * @param searchDto s
     * @param cb c
     * @param root r
     * @return Predicate
     */
    public static Predicate[] pageSet(Map<String, Field> fieldMap, SearchPage searchDto, CriteriaBuilder cb, Root<?> root) throws ParseException {

        List<ConditionItem> items = searchDto.getItems();

        //用于查询的条件
        List<Predicate> predicates=new ArrayList<>();

        if(items==null){
            items=new ArrayList<>();
        }
        for(ConditionItem item:items){
            //判断是否包含,不包含抛弃
            if(fieldMap.containsKey(item.getName())){
                //为空时不做处理
                if(CommonUtils.isNotEmpty(item.getValue())){
                    //判断
                    if(">=".equals(item.getSign()) ){
                        Predicate predicate = cb.ge(root.get(item.getName()), NumberFormat.getInstance().parse(item.getValue()));
                        predicates.add(predicate);
                    }else if("<=".equals(item.getSign())){
                        Predicate predicate = cb.le(root.get(item.getName()), NumberFormat.getInstance().parse(item.getValue()));
                        predicates.add(predicate);
                    }else if("like".equals(item.getSign())){
                        Predicate predicate = cb.like(root.get(item.getName()), "%"+item.getValue()+"%");
                        predicates.add(predicate);
                    }else if("==".equals(item.getSign())){
                        Predicate predicate = cb.equal(root.get(item.getName()), item.getValue());
                        predicates.add(predicate);
                    }

                }
            }
            //处理同字段需要比较大小的
            else if(item.getItemType().name().equalsIgnoreCase("DATE") && (item.getName().endsWith("1") || item.getName().endsWith("2"))){
                String itemName = item.getName().substring(0, item.getName().length() - 1);
                if(fieldMap.containsKey(itemName) && isNotEmpty(item.getValue())){
                    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    if(fieldMap.get(itemName).getType().equals(LocalDateTime.class)){
                        LocalDateTime parse = item.getDateValue().atStartOfDay();
                        LocalDateTime localDateTime = parse.plusDays(1);
                        if(">=".equals(item.getSign()) ){
                            predicates.add(cb.greaterThanOrEqualTo(root.get(itemName), localDateTime));
                        }else if("<=".equals(item.getSign())){
                            predicates.add(cb.lessThanOrEqualTo(root.get(itemName),localDateTime));
                        }
                    }else {
                        // 先控制在10位数 日期
                        System.out.println(item.getValue());
                        //LocalDate parse = LocalDate.parse(item.getValue().substring(0, 10), df);
                        LocalDate dateValue = item.getDateValue().plusDays(1);
                        if(">=".equals(item.getSign()) ){
                            predicates.add(cb.greaterThanOrEqualTo(root.get(itemName), dateValue));
                        }else if("<=".equals(item.getSign())){
                            // + 1
                            predicates.add(cb.lessThanOrEqualTo(root.get(itemName), dateValue));
                        }
                    }
                }
            }
        }
        //判断数据是否已经逻辑删除，已删除数据不显示在前端
        Predicate predicate = cb.equal(root.get("deleted"), false);
        predicates.add(predicate);

        return predicates.toArray(new Predicate[predicates.size()]);
    }


    /**
     *
     * @return ip
     */
    public static String  customIp(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");      // 有可能ip是代理的
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        //System.out.println("当前ip:"+ip+","+ LocalDateTime.now());
        if("0:0:0:0:0:0:0:1".equals(ip)){
            ip="127.0.0.1";
        }
        return  ip;
    }


    /**
     * 计算时间差
     * @param startDate s
     * @param endDate e
     * @return l
     */
    public static long dateDiff(Date startDate,Date endDate){
        long startTime = startDate.getTime();
        long endTime = endDate.getTime();
        long diff=endTime-startTime;
        long l = diff / (1000 * 60);
        System.out.println(l);

        return l;
    }


    /**
     * 随机生成
     * @param length 生成长度
     * @return 随机码
     */
    public static String random(int length){
        return random(length,length/2,length-length/2);
    }


    public static String random(){
        return random(6);
    }

    /**
     *
     * @param length 长度
     * @param numLength 数字个数
     * @param enLength 英文字母个数
     * @return 随机码
     */
    public static String random(int length,int numLength,int enLength){

        StringBuilder sb=new StringBuilder();

        int[] count=new int[2];

        for(int i=0;i<length;i++){
            if(count[0]>=numLength){
                sb.append(optionalChar[new Random().nextInt(optionalChar.length)]);
            }else if(count[1]>=enLength){
                sb.append(optionalNum[new Random().nextInt(optionalNum.length)]);
            }else{
                if (new Random().nextInt(2) >= 1) {
                    sb.append(optionalChar[new Random().nextInt(optionalChar.length)]);
                } else {
                    sb.append(optionalNum[new Random().nextInt(optionalNum.length)]);
                }
            }
        }
        return sb.toString();
    }
}
